#004 New Apple Event Support in DocViewer 1.1.1 IntroductionBeginning with version 1.1.1, Apple DocViewer supports a special Apple event. This Apple event is known as the "DocViewer Lookup" event. With this event, it is possible to send a message to DocViewer requesting that it open a particular document and turn to a specific heading. This DocViewer Tech Note describes the implementation of this event. Please note that tech notes 1 - 3 do not address the Viewer portion of DocViewer and are only available to licensees of the Apple DocViewer Builder.DocViewerLookup.hAccompanying this Tech Note is a C header file for many of the constants and data structures you will need when interacting programmatically with DocViewer.Event ParametersThe Lookup event accepts three parameters. These parameters are encapsulated into a single data structure for this version. (We will parameterize them at the Apple event level for the next release.) This data structure is the only parameter of the Apple event. The structure is defined as:typedef struct { FSSpec aDoc; // FSSpec for the Doc to open/search Str255 aPattern; // String in heading to find (length // prefixed) short accessLevel;// find level }SeekParamRec, *SeekParamRecPtr, **SeekParamRecHandle;The first parameter is an FSSpec to the document you wish to open and perform the lookup in. DocViewer will open this document if it isn't already open. This document must be a DocViewer document (Creator: HLX2 Type:ONLN.) If you pass a document that does not belong to DocViewer, it will return a kWrongFileType in the 'errn' parameter of the Apple event reply. The second parameter is the heading you wish DocViewer to look for. This is a simple Pascal-style string with a maximum length of 255 characters. DocViewer uses this string as a pattern to match against the document's Table of Contents. The comparison is accomplished without regard to case or diacritical marks. (e.g. FAT == fAt, fåt = fat). If the string you pass in isn't found in the document's Table of Contents, then DocViewer will return a kEntryNotFound error.The third and final parameter is used to qualify the search pattern in the second parameter. Once DocViewer has located the entry in the Table of Contents it will confirm that the entry is in the level of the TOC hierarchy specified in the accessLevel field. DocViewer supports seven levels of hierarchy. They are defined as follows:#define kFirstLevelHier 1#define kSecondLevelHier 2#define kThirdLevelHier 3#define kFourthLevelHier 4#define kFigureLevelHier 201#define kListLevelHier 202#define kTableLevelHier 203An eighth constant has been defined that will allow the entry to be found at any level in the hierarchy. In this case, if there are duplicate entries the first entry will be chosen.#define kAnyLevelHier 999Each of these selectors is mutually exclusive, and they cannot be combined (or'd) together.Sending The EventLaunch DocViewer with DocumentThe first step when sending the lookup event is to see if DocViewer is currently running. This can be accomplished with the Process manager GetProcessInfo routine. If DocViewer is found in the list of currently running processes, you should check to see that the version of DocViewer is correct (1.1.1). This can be done using the 'vers' resource with ID #1. If DocViewer is not running, it is necessary to launch the application with the target document. If DocViewer is launched without reference to the target document, it will present its default SFGetFile dialog, and you will not be able to message the application until the dialog is dismissed. For information on launching an application with a document see "LaunchwithDoc" on the latest version of the Developer CD (Tool Chest Edition).Again, when you launch the application, it is necessary to confirm that you are launching the correct version by checking the contents of the 'vers' ID #1 resource of the DocViewer application.Send the EventOnce you have determined that DocViewer is running (or you've launched it) you can then send the event. See listing 1 for an example of sending the 'seek' event.Check for ErrorsIf DocViewer cannot find the entry requested, it will return an error in the reply of the Apple event. See listing 1 for an example of how to determine these errors.Listing 1 - Sending the 'seek' Apple event//OpenDoc// This routine takes a pointer to a SeekParamRec// and sends it to DocViewer. This routine assumes// that you've already checked to see if DocViewer is running// I removed most the error checking where it was obvious// to improve readability.OSErr OpenDoc(SeekParamRec *qData){ OSErr err = noErr; AppleEvent myEvent, reply; AEDesc myAddress; long appSig = kDocViewerAppSig; long replyError = noErr; Size actualSize; DescType gotType; err = AECreateDesc( typeApplSignature,(Ptr)&appSig, sizeof(appSig),&myAddress); err = AECreateAppleEvent(kDocViewerEventClass, kSeekEventID, &myAddress, kAutoGenerateReturnID, kAnyTransactionID, &myEvent ); err = AEPutParamPtr( &myEvent, keySeekParam, typeWildCard, (Ptr)qData, sizeof(SeekParamRec) ); err = AESend( &myEvent, &reply, kAEWaitReply, kAENormalPriority, kAEDefaultTimeout, nil, nil ); // Check to see if you got an error err = AEGetParamPtr( &reply, keyErrorNumber, typeLongInteger, &gotType, (Ptr)&replyError, sizeof(long), &actualSize); // Special case on AEDescNotFound because we'll get an error // if there is no error in the reply. if ((err != noErr) && (err != errAEDescNotFound)) { return err; } // if there's an error from DocViewer return it. // otherwise return noErr. if (replyError != noErr) return replyError; else return noErr;}à d ˇ ˇˇˇˇ d ° d WORD E